package joweb

import (
	"bytes"
	"encoding/json"
	"fmt"
	"gitee.com/jolib/jokode"
	"gitee.com/jolib/jokode/jobase"
	"github.com/pkg/errors"
	"io"
	"net/http"
	"net/url"
	"strings"
	"time"
)

func HttpGet(urlPath string, params url.Values, timeOut time.Duration) ([]byte, error) {
	return HttpClientSendReq(http.MethodGet, urlPath, params, nil, timeOut)
}

func HttpPostObject(urlPath string, params url.Values, obj any, timeOut time.Duration) ([]byte, error) {
	var data []byte
	if jobase.IsNotNilObject(obj) {
		if jsonData, err := json.Marshal(obj); err != nil {
			return nil, errors.Wrapf(err, "try marshal obj to json fail")
		} else {
			data = jsonData
		}
	}

	return HttpClientSendReq(http.MethodPost, urlPath, params, data, timeOut)
}

func HttpClientSendReq(method string, urlPath string, params url.Values, data []byte, timeOut time.Duration) ([]byte, error) {
	var respBody io.ReadCloser

	defer func() {
		if respBody != nil {
			if err := respBody.Close(); err != nil {
				jokode.Errorf("try close http client fail. error info: %v", err)
			}
		}
	}()

	reqUri := strings.TrimSpace(urlPath)
	var fullUri string

	if len(params) > 0 {
		if reqUri[len(reqUri)-1] == '?' {
			fullUri = fmt.Sprintf("%s?%s", reqUri, params.Encode())
		} else {
			fullUri = fmt.Sprintf("%s%s", reqUri, params.Encode())
		}
	} else {
		fullUri = reqUri
	}

	if len(data) == 0 {
		data = make([]byte, 0)
	}

	if req, err := http.NewRequest(method, fullUri, bytes.NewReader(data)); err != nil {
		return nil, errors.Wrapf(err, "try create http request fail")
	} else {
		if len(data) > 0 {
			req.Header.Add("Content-Type", "application/json")
		}

		cli := http.Client{Timeout: timeOut}
		if resp, e1 := cli.Do(req); e1 != nil {
			return nil, errors.Wrapf(e1, "call http service fail")
		} else {
			respBody = resp.Body
			if body, err2 := io.ReadAll(respBody); err2 != nil {
				return nil, errors.Wrapf(err2, "try read resp fail")
			} else {
				return body, nil
			}
		}
	}
}
